﻿using System;
using System.Text.RegularExpressions;
using System.Windows;
using ICSharpCode.AvalonEdit;

namespace Poet
{
    class FindAndRepaceManager
    {
        public SearchItems SearchItems { get; set; }
        public bool MatchCase { get; set; }
        public bool MatchWholeWord { get; set; }
        public bool SearchUp { get; set; }
        public bool UseRegularExpression { get; set; }
        static int _indexStart, _indexEnd, _indexFind;

        public string Find(TextEditor txtBox1, string pattern)
        {
            if (string.IsNullOrEmpty(txtBox1.Text) || string.IsNullOrEmpty(pattern)) return null;

            var foundString = string.Empty;
            var strComp = MatchCase
                              ? StringComparison.Ordinal
                              : StringComparison.OrdinalIgnoreCase;

            _indexStart = txtBox1.SelectionStart + txtBox1.SelectionLength;
            _indexEnd = txtBox1.SelectionStart;

            RepeatSearch:

            if (SearchUp)
            {
                var j = 1;
                for (var i = _indexEnd - 1; i >= 0; i--, j++)
                {
                    if (UseRegularExpression)
                    {
                        var findWhat = pattern;
                        if (!MatchCase)
                            findWhat = "(?i:" + pattern + ")";

                        var regex = new Regex(findWhat);
                        var math = regex.Match(txtBox1.Text, i, j);

                        foundString = math.ToString();
                        if (string.IsNullOrEmpty(foundString)) _indexFind = -1;
                        else _indexFind = math.Index;
                    }
                    else
                    {
                        _indexFind = txtBox1.Text.IndexOf(pattern, i, j, strComp);
                        foundString = pattern;
                    }

                    if (_indexFind > 0) break;
                }
            }
            else
            {
                if (UseRegularExpression)
                {
                    var findWhat = pattern;
                    if (!MatchCase)
                        findWhat = "(?i:" + pattern + ")";

                    var regex = new Regex(findWhat);
                    var math = regex.Match(txtBox1.Text, _indexStart);

                    foundString = math.ToString();
                    if (string.IsNullOrEmpty(foundString)) _indexFind = -1;
                    else _indexFind = math.Index;
                }
                else
                {
                    _indexFind = txtBox1.Text.IndexOf(pattern, _indexStart, strComp);
                    foundString = pattern;
                }
            }

            if (MatchWholeWord && !string.IsNullOrEmpty(foundString) && _indexFind >= 0)
            {
                if (!IsWholeWord(txtBox1, foundString, _indexFind))
                {
                    _indexStart = _indexFind + foundString.Length;
                    _indexEnd = _indexFind;
                    goto RepeatSearch;
                }
            }

            txtBox1.Focus();

            if (_indexFind >= 0 && !string.IsNullOrEmpty(foundString))
            {
                txtBox1.Select(_indexFind, foundString.Length);
                txtBox1.ScrollToLine(txtBox1.TextArea.Caret.Line);
                txtBox1.ScrollToHorizontalOffset(txtBox1.TextArea.Caret.Offset);
                return foundString;
            }

            var messageBoxText = "The following specified text was not found:" +
                                 Environment.NewLine + Environment.NewLine + pattern +
                                 Environment.NewLine + Environment.NewLine +
                                 "Would you to try search again from begin?";

            if (MessageBox.Show(messageBoxText, "Find", MessageBoxButton.YesNo) != MessageBoxResult.Yes) return null;

            _indexStart = SearchUp
                              ? txtBox1.Text.Length
                              : 0;

            txtBox1.SelectionLength = 0;
            txtBox1.SelectionStart = _indexStart;
            return Find(txtBox1, pattern);
        }

        public string Replace(TextEditor txtBox1, string oldSubstring, string newSubstring, string pattern)
        {
            if (oldSubstring == txtBox1.SelectedText &&
                !string.IsNullOrEmpty(txtBox1.SelectedText))
                txtBox1.SelectedText = newSubstring;

            return Find(txtBox1, pattern);
        }       
        
        private static bool IsWholeWord(TextEditor txtBox1, string foundString, int beginWordIndex)
        {
            string previewWholeChar, followWholeChar;

            try
            {
                previewWholeChar = txtBox1.Text.Substring(beginWordIndex - 1, 1);
            }
            catch (Exception)
            {
                previewWholeChar = string.Empty;
            }

            try
            {

                followWholeChar = txtBox1.Text.Substring(beginWordIndex + foundString.Length, 1);
            }
            catch (Exception)
            {
                followWholeChar = string.Empty;
            }

            var test = previewWholeChar + foundString + followWholeChar;
            return test.Trim() == foundString;
        }
    }
}
